package com.google.code.hibernate.rest.method;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.code.hibernate.rest.EntityManager;
import com.google.code.hibernate.rest.RestInterface;
import com.google.code.hibernate.rest.internal.InternalStreams;
import com.google.code.hibernate.rest.representation.Representor;

/**
 * 
 * @author wangzijian
 * 
 */
public class GetMethodProcessor extends AbstractMethodProcessor {
	
	public GetMethodProcessor(EntityManager entityManager) {
		super(entityManager);
	}

	@Override
	protected void doProcess(URIMatchMode matchMode, HttpServletRequest request, HttpServletResponse response) throws IOException {
		Representor representor = findRepresentor(request);
		String representation = represent(representor, matchMode, request);
		if (logger.isInfoEnabled()) {
			logger.info("Response -> " + representation);
		}
		response.setContentLength(representation.length());
		response.setContentType(representor.getContentType());
		response.setCharacterEncoding(RestInterface.ENCODING);
		InternalStreams.write(representation, response.getOutputStream());
		response.setStatus(HttpURLConnection.HTTP_OK);
	}

	private String represent(Representor representor, URIMatchMode matchMode, HttpServletRequest request) {
		String uri = request.getPathInfo();
		String baseURL = getBaseURL(request);
		if (URIMatchMode.Root == matchMode) {
			Set<String> entityCategories = entityManager.getSimpleEntityNames().keySet();
			return representor.representEntityCategories(entityCategories, baseURL);
		} else if (URIMatchMode.EntityRoot == matchMode) {
			String entityName = uri.substring(1);
			List<?> entities = entityManager.list(entityName);
			return representor.representEntities(entityName, entities, baseURL);
		} else if (URIMatchMode.Entity == matchMode) {
			Map<String, String> variables = matchMode.template().match(uri);
			String entityName = variables.get("entityName");
			String id = variables.get("id");
			Object entity = entityManager.get(entityName, id);
			return representor.representEntity(entity, baseURL);
		} 
		throw new URINotMatchedException(uri);
	}

	private String getBaseURL(HttpServletRequest request) {
		String url = request.getRequestURL().toString();
		String pathInfo = request.getPathInfo();
		String base;
		if (pathInfo == null) {
			base = url;
		} else {
			base = url.substring(0, url.indexOf(pathInfo));
		}
		if (!base.endsWith("/")) {
			base += "/";
		}
		return base;
	}
	
}
